package com.lzb.compressmaster.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.text.TextUtils;
import android.util.AttributeSet;

import androidx.annotation.ColorInt;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.blankj.utilcode.util.SizeUtils;
import com.lzb.compressmaster.R;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Desc: 带文字水印的图片控件
 */
@Keep
public class WatermarkImgView extends androidx.appcompat.widget.AppCompatImageView {

    private Style style = Style.ZUO_XIE;
    private String watermarkText;
    private String watermarkText1;
    private Paint textPaint;
    private int textHeight;
    private boolean needCalculateTextPaths = false;
    private List<Path> watermarkTextPaths = new ArrayList<>();
    private List<Path> watermarkText1Paths = new ArrayList<>();
    private int watermarkTextLineSpace;

    public WatermarkImgView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public WatermarkImgView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.WatermarkImgView);
        int textSize = array.getDimensionPixelSize(R.styleable.WatermarkImgView_TextSize, SizeUtils.sp2px(18));
        int textColor = array.getColor(R.styleable.WatermarkImgView_TextColor, Color.parseColor("#AEAEAE"));
        watermarkTextLineSpace = array.getDimensionPixelSize(R.styleable.WatermarkImgView_TextLineSpace, SizeUtils.dp2px(2));
        array.recycle();

        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setTextSize(textSize);
        paint.setColor(textColor);
        textPaint = paint;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        calculateTextPaths();
        drawWatermark(canvas);
    }

    private void calculateTextPaths() {
        if (!needCalculateTextPaths) return;
        needCalculateTextPaths = false;
        watermarkTextPaths.clear();
        watermarkText1Paths.clear();
        //开始计算
        switch (style) {
            case HORIZONTAL:
                calculateForHorizontal();
                break;
            case VERTICAL:
                calculateForVertical();
                break;
            default:
                calculateForZuoXie();
                break;
        }
    }

    private void calculateForZuoXie() {
        //计算文字的高度
        int textHeight = 0;
        int watermarkTextWidth = 0;
        int watermarkText1Width = 0;
        int calTextWidth = 0;
        Rect rect = new Rect();
        if (!TextUtils.isEmpty(watermarkText)) {
            textPaint.getTextBounds(watermarkText, 0, watermarkText.length(), rect);
            textHeight = rect.height();
            watermarkTextWidth = rect.width();
            calTextWidth = watermarkTextWidth;
        }
        if (!TextUtils.isEmpty(watermarkText1)) {
            textPaint.getTextBounds(watermarkText1, 0, watermarkText1.length(), rect);
            watermarkText1Width = rect.width();
            if (calTextWidth <= 0) {
                calTextWidth = watermarkText1Width;
            }
            textHeight = Math.max(textHeight, rect.height());
        }
        this.textHeight = textHeight;
        if (calTextWidth <= 0) {
            return;
        }

        //每行的高度
        float perH = getHeight() / 7f;
        float startX = 0;
        float y = 0;
        Path path;
        for (int i = 0; i < 8; i++) {
            startX = -1.5f * getWidth();
            y = perH / 2 + perH * i;
            while (startX < getWidth()) {
                if (watermarkTextWidth > 0) {
                    path = new Path();
                    path.moveTo(startX, y);
                    path.lineTo(startX + watermarkTextWidth, y);
                    watermarkTextPaths.add(path);
                }

                if (watermarkText1Width > 0) {
                    path = new Path();
                    path.moveTo(startX, y);
                    path.lineTo(startX + watermarkText1Width, y);
                    watermarkText1Paths.add(path);
                }

                startX += 2 * calTextWidth;
            }
        }

    }

    private void calculateForHorizontal() {
        //计算文字的高度
        int textHeight = 0;
        int watermarkTextWidth = 0;
        int watermarkText1Width = 0;
        int calTextWidth = 0;
        Rect rect = new Rect();
        if (!TextUtils.isEmpty(watermarkText)) {
            textPaint.getTextBounds(watermarkText, 0, watermarkText.length(), rect);
            textHeight = rect.height();
            watermarkTextWidth = rect.width();
            calTextWidth = watermarkTextWidth;
        }
        if (!TextUtils.isEmpty(watermarkText1)) {
            textPaint.getTextBounds(watermarkText1, 0, watermarkText1.length(), rect);
            watermarkText1Width = rect.width();
            if (calTextWidth <= 0) {
                calTextWidth = watermarkText1Width;
            }
            textHeight = Math.max(textHeight, rect.height());
        }
        this.textHeight = textHeight;
        if (calTextWidth <= 0) {
            return;
        }

        //每行的高度
        float perH = getHeight() / 7f;
        float startX = 0;
        float y = 0;
        Path path;
        for (int i = 0; i < 7; i++) {
            if (i % 2 == 0) {
                startX = -calTextWidth / 2;
            } else {
                startX = calTextWidth / 2;
            }
            y = perH / 2 + perH * i;
            while (startX < getWidth()) {
                if (watermarkTextWidth > 0) {
                    path = new Path();
                    path.moveTo(startX, y);
                    path.lineTo(startX + watermarkTextWidth, y);
                    watermarkTextPaths.add(path);
                }

                if (watermarkText1Width > 0) {
                    path = new Path();
                    path.moveTo(startX, y);
                    path.lineTo(startX + watermarkText1Width, y);
                    watermarkText1Paths.add(path);
                }

                startX += 2 * calTextWidth;
            }
        }
    }

    private void calculateForVertical() {
        //计算文字的高度
        int textHeight = 0;
        int watermarkTextWidth = 0;
        int watermarkText1Width = 0;
        int calTextWidth = 0;
        Rect rect = new Rect();
        if (!TextUtils.isEmpty(watermarkText)) {
            textPaint.getTextBounds(watermarkText, 0, watermarkText.length(), rect);
            textHeight = rect.height();
            watermarkTextWidth = rect.width();
            calTextWidth = watermarkTextWidth;
        }
        if (!TextUtils.isEmpty(watermarkText1)) {
            textPaint.getTextBounds(watermarkText1, 0, watermarkText1.length(), rect);
            watermarkText1Width = rect.width();
            if (calTextWidth <= 0) {
                calTextWidth = watermarkText1Width;
            }
            textHeight = Math.max(textHeight, rect.height());
        }
        this.textHeight = textHeight;
        if (calTextWidth <= 0) {
            return;
        }

        //每行宽度
        float perW = getWidth() / 4f;
        float startY = 0;
        float x = 0;
        Path path;
        for (int i = 0; i < 4; i++) {
            if (i % 2 == 0) {
                startY = getHeight() + calTextWidth / 2;
            } else {
                startY = getHeight() - calTextWidth / 2;
            }
            x = perW / 2 + perW * i;
            while (startY > 0) {
                if (watermarkTextWidth > 0) {
                    path = new Path();
                    path.moveTo(x, startY);
                    path.lineTo(x, startY - watermarkTextWidth);
                    watermarkTextPaths.add(path);
                }

                if (watermarkText1Width > 0) {
                    path = new Path();
                    path.moveTo(x, startY);
                    path.lineTo(x, startY - watermarkText1Width);
                    watermarkText1Paths.add(path);
                }

                startY -= 2 * calTextWidth;
            }
        }
    }

    private void drawWatermark(Canvas canvas) {
        if (style == Style.ZUO_XIE) {
            canvas.save();
            canvas.rotate(-45);
        }

        float vOffset = (textHeight + watermarkTextLineSpace) / 2;
        for (Path path : watermarkTextPaths) {
            canvas.drawTextOnPath(watermarkText, path, 0, -vOffset, textPaint);
        }
        for (Path path : watermarkText1Paths) {
            canvas.drawTextOnPath(watermarkText1, path, 0, vOffset, textPaint);
        }

        if (style == Style.ZUO_XIE) {
            canvas.restore();
        }
    }

    /**
     * 获取水印文本摆放的样式
     *
     * @return
     */
    public Style getStyle() {
        return style;
    }

    /**
     * 设置水印文本摆放的样式
     *
     * @param style
     */
    public void setStyle(Style style) {
        if (this.style != style) {
            this.style = style;
            needCalculateTextPaths = true;
            invalidate();
        }
    }

    /**
     * 设置主水印文本
     *
     * @param watermarkText
     */
    public void setWatermarkText(@NonNull String watermarkText) {
        if (!Objects.equals(this.watermarkText, watermarkText)) {
            this.watermarkText = watermarkText;
            needCalculateTextPaths = true;
            invalidate();
        }
    }

    /**
     * 获取主水印文本
     *
     * @return
     */
    public String getWatermarkText() {
        return watermarkText;
    }

    /**
     * 设置副水印文本
     *
     * @param watermarkText1
     */
    public void setWatermarkText1(String watermarkText1) {
        if (!Objects.equals(this.watermarkText1, watermarkText1)) {
            this.watermarkText1 = watermarkText1;
            needCalculateTextPaths = true;
            invalidate();
        }
    }

    /**
     * 获取副水印文本
     *
     * @return
     */
    public String getWatermarkText1() {
        return watermarkText1;
    }

    /**
     * 设置水印文本字体大小
     *
     * @param textSize
     */
    public void setTextSize(float textSize) {
        if (textPaint.getTextSize() != textSize) {
            textPaint.setTextSize(textSize);
            needCalculateTextPaths = true;
            invalidate();
        }
    }

    /**
     * 获取水印文本字体大小
     *
     * @return
     */
    public float getTextSize() {
        return textPaint.getTextSize();
    }

    /**
     * 设置水印文字颜色
     *
     * @param textColor
     */
    public void setTextColor(@ColorInt int textColor) {
        textPaint.setColor(textColor);
        invalidate();
    }

    /**
     * 设置水印文字的透明度，取值范围为0-255，0表示完全透明，255表示完全不透明
     *
     * @param alpha
     */
    public void setTextAlpha(int alpha) {
        textPaint.setAlpha(alpha);
        invalidate();
    }

    /**
     * 获取水印文字的透明度
     *
     * @return
     */
    public int getTextAlpha() {
        return textPaint.getAlpha();
    }

    /**
     * 获取主水印文本与副水印文本间的行间距
     *
     * @return
     */
    public int getWatermarkTextLineSpace() {
        return watermarkTextLineSpace;
    }

    /**
     * 设置主水印文本与副水印文本间的行间距
     *
     * @param watermarkTextLineSpace
     */
    public void setWatermarkTextLineSpace(int watermarkTextLineSpace) {
        if (this.watermarkTextLineSpace != watermarkTextLineSpace) {
            this.watermarkTextLineSpace = watermarkTextLineSpace;
            invalidate();
        }
    }

    /**
     * 水印文字摆放的样式枚举常量类
     */
    public enum Style {

        ZUO_XIE("左斜"),
        HORIZONTAL("水平"),
        VERTICAL("垂直"),
        ;

        private String name;

        Style(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public static Style getStyle(int ordinal) {
            for (Style style : Style.values()) {
                if (style.ordinal() == ordinal) {
                    return style;
                }
            }
            return null;
        }
    }
}
